package org.lmind.arena.srd35.rule;

import java.util.Random;

import org.lmind.arena.srd35.BodySize;
import org.lmind.arena.srd35.Creature;
import org.lmind.arena.srd35.Damage;
import org.lmind.arena.srd35.Weapon;

public class BasicRule {

	private Random random;

	public BasicRule(Random random) {
		this.random = random;
	}
	
	public Random getRandom() {
		return random;
	}

	/**
	 * 扔骰子
	 * @param side 骰子的面数
	 * @param times 扔骰子的次数
	 * @param bonus 奖励
	 * @return
	 */
	public int roll(int side, int times , int bonus) {
		return side + random.nextInt(side * times - side) - 1 + bonus;
	}
	
	public int range(int min, int max) {
		return random.nextInt(max - min) + min;
	}

	public int abilityModifier(int value) {
		return value / 2 - 5;
	}

	public int sizeModifier(BodySize size) {
		if (size == BodySize.Colossal)
			return -8;
		else if (size == BodySize.Gargantuan)
			return -4;
		else if (size == BodySize.Huge)
			return -2;
		else if (size == BodySize.Large)
			return -1;
		else if (size == BodySize.Medium)
			return 0;
		else if (size == BodySize.Small)
			return 1;
		else if (size == BodySize.Tiny)
			return 2;
		else if (size == BodySize.Diminutive)
			return 4;
		else if (size == BodySize.Fine)
			return 8;
		else
			return 0;
	}

	public int attackBonus(Creature attacker, Weapon weapon) {
		int bonus = attacker.getBaseAttackBonus()
				+ sizeModifier(attacker.getBodySize());
		if (weapon.isMelee()) {
			bonus += abilityModifier(attacker.getStrength());
		} else {
			bonus += abilityModifier(attacker.getDexterity());
		}
		return bonus;
	}

	public int armorClass(Creature target, Weapon weapon) {
		int ac = 10 + abilityModifier(target.getDexterity())
				- sizeModifier(target.getBodySize());
		// 如果是接触攻击，则不计算装甲和盾牌的AC
		if (!weapon.isTouch() && target.getArmor() != null) {
			if (target.getArmor() != null) {
				ac += target.getArmor().getArmorBonus();
			}
			if (target.getShield() != null) {
				ac += target.getShield().getShieldBonus();
			}
		}
		return ac;
	}
	
	public int initiativeModifier(Creature creature) {
		return abilityModifier(creature.getDexterity());
	}
	
	public int initiativeCheck(Creature creature) {
		return abilityModifier(creature.getDexterity()) + roll(20, 1, 0);
	}
}
